package com.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.config.AlipayConfig;
import com.config.WeixinConfig;
import com.domain.PayEntity;
import com.dto.AlipayBean;
import com.github.wxpay.sdk.WXPayUtil;
import com.mapper.PayMapper;
import com.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 支付表 服务实现类
 * </p>
 *
 * @author sly
 * @since 2024-01-07
 */
@Service
public class PayServiceImpl extends ServiceImpl<PayMapper, PayEntity> implements PayService {

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private WeixinConfig weixinConfig;

    @Autowired
    private PayMapper payMapper;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 支付宝支付接口
     */
    @Override
    public String aliPay(AlipayBean alipayBean) {
        String pay = pay(alipayBean);
        PayEntity payEntity = new PayEntity();
        payEntity.setPayId(alipayBean.getOut_trade_no());
        payEntity.setPayName(alipayBean.getSubject());
        payEntity.setPayAmount(alipayBean.getTotal_amount());
        payEntity.setPayIntroduction(pay);
        payEntity.setCreateTime(new Date());
        payMapper.insert(payEntity);
        return pay;
    }

    public String pay(AlipayBean alipayBean) {
        String serverUrl = alipayConfig.getGatewayUrl();
        String appId = alipayConfig.getAppId();
        String privateKey = alipayConfig.getPrivateKey();
        String format = "json";
        String charset = alipayConfig.getCharset();
        String alipayPublicKey = alipayConfig.getPublicKey();
        String signType = alipayConfig.getSignType();
        String returnUrl = alipayConfig.getReturnUrl();
        String notifyUrl = alipayConfig.getNotifyUrl();
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);

        // 2、设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        // 页面跳转同步通知页面路径
        alipayRequest.setReturnUrl(returnUrl);
        // 服务器异步通知页面路径
        alipayRequest.setNotifyUrl(notifyUrl);
        // 封装参数
        alipayRequest.setBizContent(JSON.toJSONString(alipayBean));

        // 3、请求支付宝进行付款，并获取支付结果
        String result = null;
        try {
            result = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        // 返回付款信息
        return result;
    }

    @Override
    public Map<String, String> createWeixinQr(PayEntity payEntity) {
        // 先查redis
//        Map<String, String> payMap = (Map<String, String>) redisTemplate.opsForValue().get(payEntity.getPayId());
//        if (payMap != null) {
//            return payMap;
//        }
        //设置二维码参数,把参数转化为xml格式,用商户key进行加密,生成签名
        Map<String, String> paramMap = new HashMap<>();
        //商户id
        paramMap.put("appid", weixinConfig.getAppid());
        //商户号
        paramMap.put("mch_id", weixinConfig.getPartner());
        //随机字符串(唯一)
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        //商品描述
        paramMap.put("body", payEntity.getPayName());
        //商户订单号
        paramMap.put("out_trade_no", payEntity.getPayId());
        //订单金额
        String s = String.valueOf(Math.round(Double.parseDouble(payEntity.getPayAmount()) * 100));
        paramMap.put("total_fee", s);
        //当前IP
        paramMap.put("spbill_create_ip", "127.0.0.1");
        //回调地址，公网地址才行
        paramMap.put("notify_url", "http://127.0.0.1:8081/pay/weixinSuccess");
        //交易类型:    NATIVE--原生扫码支付
        paramMap.put("trade_type", "NATIVE");

        //调用微信接口,生成二维码
        Map<String, String> resultMap = null;
        try {
            String content = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder",
                    WXPayUtil.generateSignedXml(paramMap, weixinConfig.getPartnerkey()));
            //xml转换为map
            resultMap = WXPayUtil.xmlToMap(content);
            System.out.println(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 如果生成二维码成功，创建支付订单，有效2小时
        if (resultMap.get("return_code") != null && "SUCCESS".equals(resultMap.get("return_code"))) {
            // 4、封装返回结果集
            Map<String, String> map = new HashMap<>();
            map.put("orderId", payEntity.getPayId());
            map.put("totalFee", payEntity.getPayAmount());
            // 状态码
            map.put("resultCode", resultMap.get("result_code"));
            // 二维码地址
            map.put("codeUrl", resultMap.get("code_url"));

            // 存入支付信息，支付成功后修改状态
            payEntity.setPayResult(0);
            payEntity.setCreateTime(new Date());
            payEntity.setIsDel(0);
            payMapper.insert(payEntity);
            // 存储到redis中120分钟有效
            if (resultMap.get("result_code") != null) {
//            redisTemplate.opsForValue().set(payEntity.getPayId(), map, 120, TimeUnit.MINUTES);
            }
            return map;
        } else {
            throw new RuntimeException("创建微信二维码失败！");
        }
    }

    @Override
    public void alipaySuccess(String payId) {
        PayEntity payEntity = new PayEntity();
        payEntity.setPayId(payId);
        payEntity.setPayResult(1);
        payMapper.updateById(payEntity);
    }

    @Override
    public void weixinSuccess(String payResult) {
        //xml转换为map
        Map<String, String> resultMap = null;
        try {
            resultMap = WXPayUtil.xmlToMap(payResult);
            System.out.println(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果支付成功，更新支付状态
        if (resultMap.get("return_code") != null && "SUCCESS".equals(resultMap.get("return_code"))) {
            QueryWrapper<PayEntity> chatQueryWrapper = new QueryWrapper<>();
            chatQueryWrapper.lambda().eq(PayEntity::getPayId, resultMap.get("out_trade_no"))
                    .eq(PayEntity::getPayResult, 0);
            PayEntity payEntity = new PayEntity();
            payEntity.setPayResult(1);
            payMapper.update(payEntity, chatQueryWrapper);
        } else {

        }
    }

    @Override
    public String getPayResult(String payId) {
        //设置二维码参数,把参数转化为xml格式,用商户key进行加密,生成签名
        Map<String, String> paramMap = new HashMap<>();
        //商户id
        paramMap.put("appid", weixinConfig.getAppid());
        //商户号
        paramMap.put("mch_id", weixinConfig.getPartner());
        //随机字符串(唯一)
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        //商户订单号
        paramMap.put("out_trade_no", payId);
        //调用微信接口,生成二维码
        Map<String, String> resultMap = null;
        try {
            String content = HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery",
                    WXPayUtil.generateSignedXml(paramMap, weixinConfig.getPartnerkey()));
            //xml转换为map
            resultMap = WXPayUtil.xmlToMap(content);
            System.out.println(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 交易成功判断条件： return_code、result_code和trade_state都为SUCCESS
        if (resultMap.get("return_code") != null && "SUCCESS".equals(resultMap.get("result_code"))) {
            if (resultMap.get("result_code") != null && "SUCCESS".equals(resultMap.get("result_code"))) {
                if (resultMap.get("trade_state") != null && "SUCCESS".equals(resultMap.get("trade_state"))) {
                    // 就算超过2小时了，也可以把isDel改为0
                    QueryWrapper<PayEntity> updateWrapper = new QueryWrapper<>();
                    updateWrapper.lambda().eq(PayEntity::getPayId, payId).eq(PayEntity::getPayResult, 0);
                    PayEntity payEntity = new PayEntity();
                    payEntity.setPayResult(1);
                    payEntity.setIsDel(0);
                    int update = payMapper.update(payEntity, updateWrapper);
                    return "支付成功";
                }
            }
        }
        // 查询订单状态，返回给用户
        QueryWrapper<PayEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PayEntity::getPayId, payId).eq(PayEntity::getPayResult, 0)
                .eq(PayEntity::getIsDel, 0);
        PayEntity payEntity = payMapper.selectOne(queryWrapper);
        if (payEntity == null) {
            return "订单已超时";
        }
        return "订单还未支付";
    }

}
